module burp ();

	// inputs to the circuit
		reg clk_50;
		reg rst;
		reg[3:0] DIP;
		
		// wires visibly seen on diagram
		wire[3:0] inbus,
					outbus,
					alu_to_accum,
					accum_to_smr,
					smr_to_inbus,
					inbus_to_alumux,
					alumux_to_alu,
					outbus_to_alu,
					ir_low_wire,
					ir_high_wire,
					inbus_to_pclow,
					pchigh_to_eeprom,
					pclow_to_eeprom,
					fpga_reg_select,
					LED_OUT,
					fpga_ALU_S;
				
		
		
		wire[7:0] eeprom_to_ir;
		
		// needed for alu mux
		wire[3:0] constant_one;
		
		// wires used by controller for signals
		wire	CARRY_FROM_ALU;
		
		wire	sig_ir_in,
				sig_ir_out,
				sig_inc,
				sig_pc_low_in,
				sig_pc_high_in,
				sig_pchigh_rst,
				sig_pchigh_inc,
				sig_pclow_rst,
				sig_pclow_inc,
				sig_pc_low_out,
				sig_r_out,
				sig_r_in,
				sig_smr_in,
				sig_smr_out,
				sig_accum_in,
				fpga_ALU_M,
				fpga_ALU_carry,
				sig_led_reg_in,
				sig_dip_out;
				
				

					
		wire constant_zero;
		assign constant_one = 4'b0001;
		assign constant_zero = 4'b0000;
		
		wire unused1, unused2, unused3, unused4, unused5;
		
		wire[7:0] temp_sram_out, temp_sram_in;
		wire[3:0] sram_out;
		
		assign sram_out = temp_sram_out[3:0];
		
		assign temp_sram_in[7:4] = 4'b0000;
		assign temp_sram_in[3:0] = inbus;
		

		
	// -----------------------------------------
	// instantiate controller
	Controller fpga (	.CLK(clk_50),
	                  .RST(rst),
						.CARRY_FROM_ALU(~CARRY_FROM_ALU),
						.ALUcarry(fpga_ALU_carry),
						.IR({ir_high_wire, ir_low_wire}),
						.IR_IN(sig_ir_in),
						.IR_OUT(sig_ir_out),
						.PC_LOW_IN(sig_pc_low_in),
						.PC_LOW_OUT(sig_pc_low_out),
						.PC_LOW_INC(sig_pclow_inc),
						.PC_LOW_RST(sig_pclow_rst),
						.PC_HIGH_IN(sig_pc_high_in),
						.PC_HIGH_INC(sig_pchigh_inc),
						.PC_HIGH_RST(sig_pchigh_rst),
						.ACCUM_IN(sig_accum_in),
						.SMR_IN(sig_smr_in),
						.SMR_OUT(sig_smr_out),
						.REG_SELECT(fpga_reg_select),
						.R_IN(sig_r_in),
						.R_OUT(sig_r_out),
						.INC(sig_inc),
						.M(fpga_ALU_M),
						.S(fpga_ALU_S),
						.LED_REG_IN(sig_led_reg_in),
						.DIP_OUT(sig_dip_out),
						.STACK_OVERFLOW(STACK_OVERFLOW),
						.STACK_UNDERFLOW(STACK_UNDERFLOW)
					
					);
					
	BUFFER tri_sram_outbus(	.control_input(sig_r_out),
							.data_input(sram_out),
							.data_output(outbus)
						   );
						   
	BUFFER tri_pclow_outbus(	.control_input(sig_pc_low_out),
								.data_input(pclow_to_eeprom),
								.data_output(outbus)
							);
							
	BUFFER tri_smr_inbus(	.control_input(sig_smr_out),
							.data_input(smr_to_inbus),
							.data_output(inbus)
						);
								
	BUFFER tri_IR_inbus(	.control_input(sig_ir_out),
							.data_input(ir_low_wire),
							.data_output(inbus)
						);
						
	BUFFER tri_dip_inbus(	.control_input(sig_dip_out),
						.data_input(DIP),
						.data_output(inbus)
					);
						
								
	EEPROM eeprom ( 	.address( {pchigh_to_eeprom, pclow_to_eeprom} ),
						.data(eeprom_to_ir)
					);
	
	REG_374 accumulator ( 	.clk(sig_accum_in),
							.input_data(alu_to_accum),
							.output_data(accum_to_smr)
						);
						
	REG_374 SMR ( 	.clk(sig_smr_in),
					.input_data(accum_to_smr),
					.output_data(smr_to_inbus)
				);
				
	REG_374 ir_high_reg (   .clk(sig_ir_in),
							.input_data(eeprom_to_ir[7:4]),
							.output_data(ir_high_wire)
						);
		
	REG_374 ir_low_reg (	.clk(sig_ir_in),
							.input_data(eeprom_to_ir[3:0]),
							.output_data(ir_low_wire)
						);

	REG_374 led_reg (	.clk(sig_led_reg_in),
							.input_data(outbus),
							.output_data(LED_OUT)
	);	
					
	MUX_2to1x4 mux (	.select_line(sig_inc),
						.input_A(inbus),
						.input_B(constant_one),
						.output_mux(alumux_to_alu)
					);
	
	PC_163 PC_high_ctr ( 	.reset(~sig_pchigh_rst),
							.parallel_input(inbus),
							.parallel_enable(~sig_pc_high_in),
							.Q(pchigh_to_eeprom),
							.clock(clk_50),
							.count_en(~sig_pchigh_inc),
							.TC(unused1)
						);
	PC_163 PC_low_ctr ( 	.reset(~sig_pclow_rst),
							.parallel_input(inbus),
							.parallel_enable(~sig_pc_low_in),
							.Q(pclow_to_eeprom),
							.clock(clk_50),
							.count_en(~sig_pclow_inc),
							.TC(unused2)
						);
							

	SRAM sram		(	.ce_r(~sig_r_out), // active low
						.oe_r(sig_r_out), // active high
						.rw_r(1'b1), // 1 = read... right side always reads
						.address_r(fpga_reg_select),
						.data_out_r(temp_sram_out),
						.ce_l(~sig_r_in), // active low
						.oe_l(sig_r_in),
						.rw_l(1'b0), // 0 = write... left side always writes
						.address_l(fpga_reg_select),
						.data_out_l(temp_sram_in)
					);
	
	
	Circuit74181 alu (		.S(fpga_ALU_S),
							.A(alumux_to_alu),
							.B(outbus),
							.M(fpga_ALU_M),
							.CNb(~fpga_ALU_carry),
							.F(alu_to_accum),
							.X(unused3),
							.Y(unused4),
							.CN4b(CARRY_FROM_ALU),
							.AEB(unused5)
					);
					
	
						
							
	//------------------------------------------
	// create 5 KHz clock
	always begin
	#200000 clk_50 = ~clk_50;
	//#500000 DIP = DIP + 1;
	end
	// -----------------------------------------

	initial
	begin
		
		$display($time, " << Starting simulation >> ");
		clk_50 = 1'b0;
		rst    = 1'b1;
		DIP = 4'b1111;
		
		#20 rst = 1'b0; // clear reset at time 20.
		$display($time, " << Coming out of reset >> ");
		
	end

	/* in the verilog sim console, we add the waveforms
	   we want to see (typically LED_OUT which shows the
	   output of a command if we use the OUT operation...
	   
	   then we type: run 20000 
	   or something large like that.
	*/
	

	
endmodule